package com.ck.common.utils.txt;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 字符文本类工具
 * @author ck
 */
@Slf4j
public class TextUtil {
    private static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
            "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
            "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z"};


    private static Pattern NUMBER_PATTERN = Pattern.compile("[0-9]*");

    /**
     * 判断是否是正整数
     *
     * @param string
     * @return
     */
    public static boolean isNumeric(String string) {
        return NUMBER_PATTERN.matcher(string).matches();
    }

    /**
     * 生成8位不重复的随机码
     *
     * @return short_uuid
     */
    public static String generateShortUuid() {
        StringBuilder shortBuffer = new StringBuilder();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        int uuidLen = 8;
        for (int i = 0; i < uuidLen; i++) {
            String str = uuid.substring(i * 4, i * 4 + 4);
            int x = Integer.parseInt(str, 16);
            shortBuffer.append(chars[x % 0x3E]);
        }
        return shortBuffer.toString();
    }


    /**
     * 生成32位小写UUID
     *
     * @return uuid
     */
    public static String createDefaultUuid() {
        UUID randUuid = UUID.randomUUID();
        String uuid = randUuid.toString();
        uuid = uuid.replace("-", "");
        return uuid;
    }

    /**
     * 字符串数组[1,2,3] 转换成用于SQL查询的 1,2,3 格式
     *
     * @param arr
     * @return
     */
    public static String arrToSqlCellStr(String[] arr) {

        if (arr == null) {
            return "";
        }

        // 数组转换为X,X
        String idArr = Arrays.toString(arr).replace("[", "").replace("]", "");
        return idArr;
    }

    /**
     * 获取最大length长度的文本
     *
     * @param txt
     * @param length
     * @return
     */
    public static String getTxt(String txt, int length) {
        if (StringUtils.isEmpty(txt)) {
            return "";
        }

        if (txt.length() > length) {
            txt = txt.substring(0, length);
        }
        return txt;
    }

    /**
     * 正则匹配
     *
     * @param txt
     * @param reg
     * @return
     */
    public static Boolean validReg(String txt, String reg) {
        return txt.matches(reg);
    }


    /**
     * 字节转16进制字符串
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString().toUpperCase();
    }

    /**
     * 16进制字符串转字节
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (StringUtils.isEmpty(hexString)) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * 字符转字节
     *
     * @param c
     * @return
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    /**
     * 验证参数是否符合列表值
     *
     * @param param
     * @param list
     * @return
     */
    public static Boolean validParamInList(String param, List<String> list) {
        if (StringUtils.isEmpty(param)) {
            return false;
        }

        boolean flag = false;
        for (String item : list) {
            if (item.equals(param)) {
                flag = true;
                break;
            }
        }
        return flag;
    }


    /**
     * 补足分机号至6位,前补0
     *
     * @param extNo
     * @return
     */
    public static String transExtNo(String extNo) {
        String rst = StringUtils.trimToEmpty(extNo);

        // 为空 或 非数字
        if (StringUtils.isEmpty(extNo) || !StringUtils.isNumeric(extNo)) {
            return rst;
        }

        // 前补0
        int no = Integer.parseInt(extNo);
        rst = String.format("%6d", no);
        return rst;
    }

    /**
     * 保留字符串中的数值部分
     *
     * @param txt
     * @return
     */
    public static String leftNumberText(String txt) {
        return StringUtils.trimToEmpty(txt).replaceAll("[^0-9]", "");
    }

    /**
     * 对文本进行urlencode
     *
     * @param str
     * @return
     */
    public static String urlEncode(String str) {
        String enMessage = null;
        try {
            enMessage = URLEncoder.encode(str, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return enMessage;
    }


    /**
     * byte数组转hex
     *
     * @param bytes
     * @return
     */
    public static String byteToHex(byte[] bytes) {
        String strHex = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < bytes.length; n++) {
            strHex = Integer.toHexString(bytes[n] & 0xFF);
            // 每个字节由两个字符表示，位数不够，高位补0
            sb.append((strHex.length() == 1) ? "0" + strHex : strHex);
        }
        return sb.toString().trim();
    }


    /**
     * 将错误信息转为字符串
     *
     * @param e
     * @return
     */
    public static String ex2Txt(Throwable e) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        e.printStackTrace(new PrintStream(baos));
        return baos.toString();
    }

    public static String format(String msg, Object... args) {
        if (null != args && args.length > 0) {
            for (Object arg : args) {
                msg = StringUtils.replaceOnce(msg, "{}", String.valueOf(arg));
            }
        }
        return msg;
    }

    /**
     * MD5加密工具类
     *
     * @param s
     * @return
     * @author hezhao
     */
    public static String buildMd5Txt(String s) {

        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F'};

        try {
            byte[] strTemp = s.getBytes();
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char[] str = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            log.error("MD5生成异常: " + ex2Txt(e));
            return "";
        }
    }


    /**
     * Object对象转字符串类型
     *
     * @param obj
     * @return
     */
    public static String obj2Txt(Object obj) {
        return obj == null ? "" : StringUtils.trimToEmpty(String.valueOf(obj));
    }

}
